public class demo {

    // start 和 run 区别
    public static void main567(String[] args) throws InterruptedException {
//        线程
        Thread t = new Thread(()->{
            while (true) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
//        t.start();//交替打印 hello main    和    hello thread
        t.run();//只打印  hello thread
//        run只是一个普通方法
//        你在main线程里调用run 其实并没有创建新的线程
//        这个循环仍是在main中执行  按循序执行 但是在t中一直循环 所以一直打印hello thread
//        所以我们可以更改t中的循环 如for(i=0;i<5;i++) 打印完之后会继续打印hello main


//        main方法
        while (true) {
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }















    //  中断线程
//    1.
    private static boolean flag = false;//设置标志位让线程终止 但是这种写法不够严谨
    public static void main1(String[] args) {
        Thread t = new Thread(()->{
            while (!flag) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag = true;
        System.out.println("终止线程t");
    }

//    打印结果:
//      hello thread
//      hello thread
//      hello thread
//      hello thread
//      hello thread
//      终止线程t
//
//    这里要注意  此处是多个线程公用同一个虚拟地址空间 因此main线程修改flag和t线程判定的flag是同一个值



    //    2.更好的方法 通过Thread内置标志位
//      Thread.interrupted()  这是一个静态方法
//      Thread.currentThread().isInterrupted()  这是一个实例方法其中currentThread能获取到当前对象的实例
    public static void main345(String[] args) {
        Thread t = new Thread(()->{
            while (!Thread.currentThread().isInterrupted()) {//这里的 ! 不能忘记
                System.out.println("hello threadddd");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println("这里可以添加一些收尾操作");
                    break;//没有break会 打完4个hello threadddd后会打印异常 然后继续打印hello threadddd
                }
            }
        });
        t.start();

        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        在主线中通过调用interrupt()这个方法来 中断这个线程
//        t.interrupt()的意思就是让t的线程被中断
        t.interrupt();
//        但是这里有会出现两个问题
//        1.如果t线程处于就绪状态 就设置线程的标志位为true
//        2.(是我们当前这群情况)如果t线程处于堵塞状态(sleep休眠状态) 就会触发一个InterruptException
//           所以 可以通过在触发的异常中加一个终止条件break 这样问题就解决可了
//        如果我们点运行打完4个hello threadddd后会打印异常 然后继续打印hello threadddd
//        然而这并不是我们想要的



//        如果我们的代码线程有很多个
//        public static boolean interrupted()           判断当前线程的中断标志位是否设置，调用后清除标志位(是静态的)
//        public boolean isInterrupted()                判断对象关联的线程的标志位是否设置，调用后不清除标志位(无脑使用第二个)
//
//        Thread.interrupted();
//        Thread.currentThread().interrupt();//使用这一个
    }













    //    线程等待
//    其中一种控制线程执行顺序的手段 控制线程结束的先后顺序 因为多线程调度顺序是不确定的
//    join
//    调用join的时候 哪个线程调用join那个线程就会堵塞等待 得到对应线程执行完毕为止(对应线程的run执行完)
    public static void main123(String[] args) {
        Thread t = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();


//        主线程中可以使用一个等待操作 来等待t线程执行结束
//          调用join之后, main线程就会进入阻塞状态(暂时无法在cpu.上执行)
//          代码执行到join这一行,就暂时停下了，不继续往下执行了~~
//          然后join啥时候能继续往下走,恢复成就绪状态呢?就是等到t线程执行完毕(run方法跑完了)
//          通过线程等待,就是在控制让t先结束, main后结束~~ - -定程度上的干预了这两个线程的执行顺序~-
        try {
//            t.join();//t线程执行结束才执行主线程
            t.join(3000);//这种情况表示主线程最多堵塞3秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 5; i++) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }




    //    获取线程实例
//    Thread.currentThread(就能够获取到当前线程的引用)
//    (Thread实例的引用)哪个线程调用的这个currentThread,就获取到的是哪个线程的实例~~
    public static void main12(String[] args) {
        Thread t = new Thread() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());//Thread-0未命名 默认名字



//            对于这个代码来说，是通过继承Thread的方式来创建线程.此时在run方法中，
//            直接通过this ,拿到的就是当前Thread的实例~
                System.out.println(this.getName());//Thread-0
            }
        };
        t.start();

        System.out.println(Thread.currentThread().getName());//main
    }

    public static void main13(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
//                System.out.println(this.getName());//getName()报红 error
//                此处的this不是指向Thread类型了.而是指向Runnable.而Runnable只是一个单纯的任务，没有name属性的~
//                要想拿到线程的名字~~只能通过Thread.currentThread


                System.out.println(Thread.currentThread().getName());//Thread-0
//                lambda表达式同这里的效果
            }
        });
        t.start();
    }





//    线程的休眠 sleep  针对Linux系统
//    进程，PCB+双向链表~~这个说法是针对只有一 个线程的进程是如此的一-
//如果是一个进程有多个线程此时每个线程都有一个PCB一个进程对应的就是一组PCB了~~
//PCB上有一个字段tgroupid,这个id其实就相当于进程的id. 同一个进程中的若干个线程的pid是相同的!!
//process control block 进程控制块?和线程有啥关系?
//其实Linux内核不区分进程和线程
//进程线程是程序猿写应用程序代码搞出来的词实际上Linux内核只认PCB !在内核里Linux把线程称为轻量级进程~~

//
//    如果某个线程调用了sleep方法这个PCB就会进入到阻塞队列~
//操作系统调度线程的时候就只是从就绪队列中挑选合适的PCB到CPU上运行~~阻塞队列里的PCB就只能干等着~~
//当睡眠时间到了~一     系统就会把刚才这个PCB从阻塞队列挪回到就绪队列~
//内核中的很多工作都依赖大量的数据结构~~
//但凡是需要管理很多数据的程序，都大量的依赖数据结构~~
}
